#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
#include "io.h"
#include "graphics.h"

// 添加函数原型声明
void terminal_putentryat(unsigned char c, uint32_t color, size_t x, size_t y);

// 实现字符绘制函数


// 声明全局图形信息指针
GraphicsInfo* graphics_info = NULL;

// 添加串口输出函数
void serial_putchar(char c) {
    while ((inb(0x3F8 + 5) & 0x20) == 0);
    outb(0x3F8, c);
}

void serial_writestring(const char* str) {
    for (size_t i = 0; str[i] != '\0'; i++) {
        serial_putchar(str[i]);
    }
}

// 替换VGA缓冲区为UEFI帧缓冲区
static volatile uint32_t* vga_buffer;
static size_t VGA_WIDTH;  // 修改为非常量
static size_t VGA_HEIGHT; // 修改为非常量
static size_t terminal_row;
static size_t terminal_column;

// 统一terminal_color为uint32_t类型
static uint32_t terminal_color;

// 更新颜色函数以支持RGB
uint32_t vga_entry_color(uint8_t r, uint8_t g, uint8_t b) {
    return (r << 16) | (g << 8) | b;
}

// 更新终端初始化函数
void terminal_initialize(void) {
    // 使用UEFI提供的图形信息
    vga_buffer = (volatile uint32_t*)graphics_info->framebuffer;
    VGA_WIDTH = graphics_info->width;
    VGA_HEIGHT = graphics_info->height;
    terminal_row = 0;
    terminal_column = 0;
    terminal_color = vga_entry_color(200, 200, 200); // 浅灰色

    // 清空屏幕
    for (size_t y = 0; y < VGA_HEIGHT; y++) {
        for (size_t x = 0; x < VGA_WIDTH; x++) {
            const size_t index = y * (graphics_info->pitch / 4) + x;
            vga_buffer[index] = 0; // 黑色
        }
    }
}

void terminal_setcolor(uint8_t color) {
    terminal_color = color;
}

// 添加整数转字符串函数实现
char* itoa(int num, char* str, int base) {
    int i = 0;
    int isNegative = 0;

    // 处理0的情况
    if (num == 0) {
        str[i++] = '0';
        str[i] = '\0';
        return str;
    }

    // 如果是负数且基数为10，添加负号
    if (num < 0 && base == 10) {
        isNegative = 1;
        num = -num;
    }

    // 转换数字为字符串
    while (num != 0) {
        int rem = num % base;
        str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
        num = num / base;
    }

    // 添加负号
    if (isNegative) {
        str[i++] = '-';
    }

    str[i] = '\0'; // 结束符

    // 反转字符串
    int start = 0;
    int end = i - 1;
    while (start < end) {
        char temp = str[start];
        str[start] = str[end];
        str[end] = temp;
        start++;
        end--;
    }

    return str;
}

void terminal_putchar(char c) {
    if (c == '\n') {
        terminal_row++;
        terminal_column = 0;
        return;
    }
    terminal_putentryat((unsigned char)c, terminal_color, terminal_column, terminal_row);
    if (++terminal_column == VGA_WIDTH) {
        terminal_column = 0;
        if (++terminal_row == VGA_HEIGHT)
            terminal_row = 0;
    }
}

void terminal_write(const char* data, size_t size) {
    for (size_t i = 0; i < size; i++)
        terminal_putchar(data[i]);
}

// 自定义字符串长度函数
size_t strlen(const char* str) {
    size_t len = 0;
    while (str[len] != '\0') {
        len++;
    }
    return len;
}

void terminal_writestring(const char* data) {
    terminal_write(data, strlen(data));
}

// 键盘扫描码到ASCII的映射表（简化版）
static const char scancode_to_ascii[] = {
    0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
    '\t','q','w','e','r','t','y','u','i','o','p','[',']','\n', 0, 'a','s','d','f','g','h','j','k','l',';', '\'', '`', 0,
    '\\','z','x','c','v','b','n','m', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

// 键盘输入函数实现
char keyboard_getchar(void) {
    uint8_t scancode;
    
    // 等待键盘输入
    while ((inb(0x64) & 0x01) == 0);
    
    // 读取扫描码
    scancode = inb(0x60);
    
    // 只处理按下事件（忽略释放事件）
    if (scancode < 0x80) {
        return scancode_to_ascii[scancode];
    }
    
    return 0;
}

// 简单的命令行输入读取
char* read_line() {
    static char buffer[256];
    size_t index = 0;
    
    while (1) {
        char c = keyboard_getchar(); // 需要实现键盘输入函数
        if (c == '\n') {
            buffer[index] = '\0';
            terminal_putchar('\n');
            return buffer;
        } else if (c == '\b' && index > 0) {
            index--;
            terminal_putchar('\b');
            terminal_putchar(' ');
            terminal_putchar('\b');
        } else if (c >= ' ' && c <= '~' && index < 255) {
            buffer[index++] = c;
            terminal_putchar(c);
        }
    }
}

// 内核主函数，接收EFI传递的图形信息
void kernel_main(GraphicsInfo* info) {
    // 添加串口调试输出
    serial_writestring("Kernel main started\n");
    
    // 初始化全局图形信息指针
    graphics_info = info;
    serial_writestring("Graphics info initialized\n");
    
    // 初始化终端
    terminal_initialize();
    serial_writestring("Terminal initialized\n");
    
    // 显示启动信息
    terminal_writestring("TheFirstPageOS booted successfully!\n");
    
    // 显示分辨率信息
    if (graphics_info) {
        terminal_writestring("Resolution: ");
        char width_str[10];
        char height_str[10];
        itoa(graphics_info->width, width_str, 10);
        itoa(graphics_info->height, height_str, 10);
        terminal_writestring(width_str);
        terminal_writestring("x");
        terminal_writestring(height_str);
        terminal_writestring("\n");
    } else {
        terminal_writestring("Failed to get graphics information\n");
    }
    terminal_writestring("\n> ");

    while (1) {
        char* command = read_line();
        terminal_writestring("Command: ");
        terminal_writestring(command);
        terminal_writestring("\n> ");
    }
}

// 添加8x8字体定义
static const uint8_t font[96][8] = {
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 空格 (32)
    {0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00}, // !
    {0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00}, // "
    {0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x00, 0x00}, // #
    {0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x00, 0x00}, // $
    {0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x00, 0x00}, // %
    {0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00, 0x00}, // &
    {0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // '
    {0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00}, // (
    {0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x00}, // )
    {0x14, 0x08, 0x3E, 0x08, 0x14, 0x00, 0x00, 0x00}, // *
    {0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00}, // +
    {0x00, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00}, // ,
    {0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00}, // -
    {0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, // .
    {0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00}, // /
    {0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00, 0x00}, // 0
    {0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00}, // 1
    {0x42, 0x61, 0x51, 0x49, 0x46, 0x00, 0x00, 0x00}, // 2
    {0x21, 0x41, 0x45, 0x4B, 0x31, 0x00, 0x00, 0x00}, // 3
    {0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x00, 0x00}, // 4
    {0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x00, 0x00}, // 5
    {0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00, 0x00, 0x00}, // 6
    {0x01, 0x71, 0x09, 0x05, 0x03, 0x00, 0x00, 0x00}, // 7
    {0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00}, // 8
    {0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x00}, // 9
    {0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00}, // :
    {0x00, 0x56, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00}, // ;
    {0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00}, // <
    {0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00}, // =
    {0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00}, // >
    {0x02, 0x01, 0x51, 0x09, 0x06, 0x00, 0x00, 0x00}, // ?
    {0x32, 0x49, 0x79, 0x41, 0x3E, 0x00, 0x00, 0x00}, // @
    {0x7E, 0x11, 0x11, 0x11, 0x7E, 0x00, 0x00, 0x00}, // A
    {0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00}, // B
    {0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00, 0x00}, // C
    {0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x00}, // D
    {0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x00, 0x00}, // E
    {0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00, 0x00}, // F
    {0x3E, 0x41, 0x49, 0x49, 0x7A, 0x00, 0x00, 0x00}, // G
    {0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x00}, // H
    {0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x00, 0x00}, // I
    {0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, 0x00, 0x00}, // J
    {0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00}, // K
    {0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, // L
    {0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x00, 0x00, 0x00}, // M
    {0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x00, 0x00}, // N
    {0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x00, 0x00}, // O
    {0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00}, // P
    {0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x00, 0x00}, // Q
    {0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x00, 0x00}, // R
    {0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x00, 0x00}, // S
    {0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, 0x00, 0x00}, // T
    {0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00}, // U
    {0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x00, 0x00}, // V
    {0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, 0x00, 0x00}, // W
    {0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x00, 0x00}, // X
    {0x07, 0x08, 0x70, 0x08, 0x07, 0x00, 0x00, 0x00}, // Y
    {0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x00, 0x00}, // Z
    {0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00}, // [
    {0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00}, // backslash
    {0x00, 0x41, 0x41, 0x7F, 0x00, 0x00, 0x00, 0x00}, // ]
    {0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00}, // ^
    {0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00}, // _
    {0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00}, // `
    {0x20, 0x54, 0x54, 0x54, 0x78, 0x00, 0x00, 0x00}, // a
    {0x7F, 0x48, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00}, // b
    {0x38, 0x44, 0x44, 0x44, 0x20, 0x00, 0x00, 0x00}, // c
    {0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, 0x00, 0x00}, // d
    {0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00, 0x00}, // e
    {0x08, 0x7E, 0x09, 0x01, 0x02, 0x00, 0x00, 0x00}, // f
    {0x0C, 0x52, 0x52, 0x52, 0x3E, 0x00, 0x00, 0x00}, // g
    {0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00}, // h
    {0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, 0x00, 0x00}, // i
    {0x20, 0x40, 0x44, 0x3D, 0x00, 0x00, 0x00, 0x00}, // j
    {0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00}, // k
    {0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00}, // l
    {0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, 0x00, 0x00}, // m
    {0x7C, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00}, // n
    {0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00}, // o
    {0x7C, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00}, // p
    {0x08, 0x14, 0x14, 0x14, 0x7C, 0x00, 0x00, 0x00}, // q
    {0x7C, 0x08, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00}, // r
    {0x48, 0x54, 0x54, 0x54, 0x20, 0x00, 0x00, 0x00}, // s
    {0x04, 0x3F, 0x44, 0x40, 0x20, 0x00, 0x00, 0x00}, // t
    {0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, 0x00, 0x00}, // u
    {0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, 0x00, 0x00}, // v
    {0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, 0x00, 0x00}, // w
    {0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00}, // x
    {0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00, 0x00, 0x00}, // y
    {0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x00, 0x00}, // z
    {0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x00}, // {
    {0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00}, // |
    {0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x00, 0x00}, // }
    {0x10, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00}, // ~
    {0x78, 0x46, 0x41, 0x46, 0x78, 0x00, 0x00, 0x00}  // DEL
};

// 更新字符渲染函数
void terminal_putentryat(unsigned char c, uint32_t color, size_t x, size_t y) {
    // 检查字符是否在可打印范围内
    if (c < 32 || c >= 128) return;
    
    // 获取字体数据
    const uint8_t* char_data = font[c - 32];

    // 渲染8x8字符
    for (int row = 0; row < 8; row++) {
        for (int col = 0; col < 8; col++) {
            // 检查当前像素是否应该被绘制
            if (char_data[row] & (1 << (7 - col))) {
                size_t pixel_x = x * 8 + col;
                size_t pixel_y = y * 8 + row;
                
                // 检查是否超出屏幕边界
                if (pixel_x < VGA_WIDTH && pixel_y < VGA_HEIGHT) {
                    size_t index = pixel_y * (graphics_info->pitch / 4) + pixel_x;
                    vga_buffer[index] = color;
                }
            }
        }
    }
}